﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;


namespace 数学.解析几何
{

   public class 坐标转换
    {


        /// <summary>
        ///操纵点绕旋转中心旋转一定的角度后的最终坐标。
        ///角度为弧度,逆时针为正，顺时针为负
        /// </summary>
        public static  PointF 坐标旋转(PointF 操纵点, PointF 旋转中心, double 旋转角度)
            {
                PointF 结果=new PointF();
                double X,Y;

                 X = 旋转中心.X + (操纵点.X - 旋转中心.X) * Math.Cos(旋转角度) - (操纵点.Y - 旋转中心.Y) * Math.Sin(旋转角度);
                 Y = 旋转中心.Y + (操纵点.X - 旋转中心.X) * Math.Sin(旋转角度) + (操纵点.Y - 旋转中心.Y) * Math.Cos(旋转角度);

                结果.X = (float)X;
                结果.Y = (float)Y;
            
                return 结果;
            }


        /// <summary>
        ///已知两点坐标以及所在圆的弧度角，求半径     
        /// </summary>
        public static double 求半径(PointF P1,PointF P2,double 夹角)
        {
            double R;
            double L;

            L = Math.Sqrt((P2.X-P1.X)* (P2.X - P1.X)+ (P2.Y - P1.Y) * (P2.Y - P1.Y));
            R = 求半径(L, 夹角);
                
            return R;
        }


        /// <summary>
        ///已知弦长以及弧度角，求半径
        /// </summary>
        public static double 求半径(double 弦长, double 夹角)
        {
            double R;

            if(夹角==Math.PI)
            {
                return 弦长 / 2;
            }
            else if(夹角 > Math.PI)
            {
                夹角 = Math.PI - 夹角;
            }

            R = Math.Sqrt(弦长 * 弦长 * 0.5 / (1 - Math.Cos(夹角)));

            return R;
        }


    

        /// <summary>
        ///已知圆上的两点和半径，从起始点顺时针画弧，求圆心
        /// </summary>
         /// <param name="R">起始点以及终止点所在圆的半径</param>
        public static PointF 求圆心(PointF 起始点,PointF 终止点,double R)
        {
            double L, H;      //L=弦长 H
            PointF LL = new PointF();   //终止点相对于起始点的相对坐标
            PointF LLC = new PointF();   //缩放到H长度后的相对坐标
            PointF LLJ = new PointF();   //缩放到H长度后的绝对坐标
            PointF Pc = new PointF();    //旋转中心坐标
            PointF Sca = new PointF();

            LL = PointF_Sub(起始点, 终止点);
            L = Math.Sqrt(LL.Y * LL.Y + LL.X * LL.X);
            H = Math.Sqrt(R * R - L * L / 4);
            Sca.X = (float)(H / L);
            Sca.Y = (float)(H / L);
            LLC = PointF_Scal(LL, Sca);
            Pc = PointF_Scal(PointF_Add(起始点, 终止点),new PointF(0.5f,0.5f));
            LLJ = PointF_Add(LLC, Pc);
            return 坐标旋转(LLJ,Pc,Math.PI/2);
        }

        /// <summary>
        ///将P1相对P2的坐标加到P2上，换算出P1在P2所在坐标系的绝对坐标
        /// </summary>
        /// <param name="P1">相对P2的坐标</param>
        /// <param name="P2">P2在其坐标系内的绝对坐标</param>
        public static PointF PointF_Add(PointF P1, PointF P2)
        {
            PointF P=new PointF();

            P.X = P1.X + P2.X;
            P.Y = P1.Y + P2.Y;

            return P;
        }

        /// <summary>
        ///换算出P1相对P2的相对坐标
        /// </summary>
        /// <param name="P1">在坐标系内的坐标</param>
        /// <param name="P2">在坐标系内的坐标</param>
        public static PointF PointF_Sub(PointF P1, PointF P2)
        {
            PointF P = new PointF();

            P.X = P1.X - P2.X;
            P.Y = P1.Y - P2.Y;

            return P;
        }


        /// <summary>
        ///将P1坐标按照P2的缩放比例放大后的坐标
        /// </summary>
        /// <param name="P1">在坐标系内的坐标</param>
        /// <param name="Scal">缩放比例</param>
        public static PointF PointF_Scal(PointF P1, PointF Scal)
        {
            PointF P = new PointF();

            P.X = P1.X * Scal.X;
            P.Y = P1.Y * Scal.Y;

            return P;
        }




    }
}
